package com.xiaoan.wlt.common.jfinal;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.generator.BaseModelGenerator;
import com.jfinal.plugin.activerecord.generator.ColumnMeta;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.xiaoan.wlt.utils.Common;

/**
 * baseModel 生成类
 * 1、增加生成单模型条件拼接
 * @author liangjiahong
 * @date 2016年12月9日
 */
public class MyBaseModelGenerator extends BaseModelGenerator {
	public MyBaseModelGenerator(String baseModelPackageName, String baseModelOutputDir) {
		super(baseModelPackageName, baseModelOutputDir);
	}
	
	protected String importTemplate =
			"import com.xiaoan.wlt.common.jfinal.BaseModel;%n" +
			"import com.jfinal.plugin.activerecord.IBean;%n%n";
	protected String classDefineTemplate =
		"/**%n" +
		" * Generated by JFinal, do not modify this file.%n" +
		" */%n" +
		"@SuppressWarnings(\"serial\")%n" +
		"public abstract class %s<M extends %s<M>> extends BaseModel<M> implements IBean {%n%n";
	
	protected String where = "\tpublic static final String TABLE = \" %s \";%n";
	protected void genBaseModelContent(TableMeta tableMeta) {
		StringBuilder ret = new StringBuilder();
		genPackage(tableMeta,ret);
		genImport(ret);
		genClassDefine(tableMeta, ret);
		for (ColumnMeta columnMeta : tableMeta.columnMetas) {
			genSetMethodName(columnMeta, ret);
			genGetMethodName(columnMeta, ret);
		}
		genSql(tableMeta, ret);
		ret.append(String.format("}%n"));
		tableMeta.baseModelContent = ret.toString();
	}
	
	
	protected void genImport(StringBuilder ret) {
		ret.append(String.format(importTemplate));
		
		ret.append(String.format("import %s.%s;%n%n", "org.apache.commons.lang3","StringUtils"));
		ret.append(String.format("import %s.%s;%n%n", "com.xiaoan.wlt.common","WhereAndParas"));
		ret.append(String.format("import %s.%s;%n%n", "java.util","ArrayList"));
		ret.append(String.format("import %s.%s;%n%n", "java.util","List"));
//		ret.append(String.format("import %s.%s;%n%n", "com.jfinal.plugin.activerecord","Page"));
	}
	
	protected void genClassDefine(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(classDefineTemplate, tableMeta.baseModelName, tableMeta.baseModelName));
	}
	
	protected void genPackage(TableMeta tableMeta, StringBuilder ret) {
		
		String tableName = tableMeta.name;
		String fullTabelName = StrKit.firstCharToUpperCase(StrKit.toCamelCase(tableName));
		String pack = fullTabelName.replace(tableMeta.baseModelName.replace("Base", ""), "");
		pack = Common.underscoreName(pack);
		pack = "."+pack.toLowerCase().replace("_",".");
		ret.append(String.format(packageTemplate, baseModelPackageName + pack));
	}
	
	private void genSql(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(where, tableMeta.name));
		ret.append(String.format("\tpublic WhereAndParas getWhereAndParas(%s %s){%n",tableMeta.baseModelName,toLowerCaseFirstOne(tableMeta.modelName)));
		ret.append(String.format("\t\tStringBuffer sql = new StringBuffer();%n"));
		ret.append(String.format("\t\tList<Object> list = new ArrayList<Object>();%n"));
		ret.append(String.format("\t\tWhereAndParas wap = new WhereAndParas();%n"));
		for (ColumnMeta columnMeta : tableMeta.columnMetas) {
			if(columnMeta.javaType.indexOf("String")!= -1){
				ret.append(String.format("\t\tif(StringUtils.isNotEmpty(%s.get%s())){%n",toLowerCaseFirstOne(tableMeta.modelName),captureName(columnMeta.attrName)));
				ret.append(String.format("\t\t\tsql.append(\" and o.%s like ?\");%n",columnMeta.name));
				ret.append(String.format("\t\t\tlist.add(\"%s\"+%s.get%s()+\"%s\");%n","%",toLowerCaseFirstOne(tableMeta.modelName),captureName(columnMeta.attrName),"%"));
				ret.append(String.format("\t\t}%n"));
			}else if(columnMeta.javaType.indexOf("Integer") != -1 ||
					columnMeta.javaType.indexOf("Long") != -1 ||
					columnMeta.javaType.indexOf("Double") != -1 ||
					columnMeta.javaType.indexOf("Float") != -1){
				ret.append(String.format("\t\tif(%s.get%s() != null && %s.get%s() > 0){%n",toLowerCaseFirstOne(tableMeta.modelName),captureName(columnMeta.attrName),toLowerCaseFirstOne(tableMeta.modelName),captureName(columnMeta.attrName)));
				ret.append(String.format("\t\t\tsql.append(\" and o.%s = ?\");%n",columnMeta.name));
				ret.append(String.format("\t\t\tlist.add(%s.get%s());%n",toLowerCaseFirstOne(tableMeta.modelName),captureName(columnMeta.attrName)));
				ret.append(String.format("\t\t}%n"));
			}
		}
		ret.append(String.format("\t\twap.setWhere(sql.toString());%n"));
		ret.append(String.format("\t\twap.setParas(list.toArray());%n"));
		ret.append(String.format("\t\treturn wap;%n"));
		ret.append(String.format("\t}%n"));
	}

	// 首字母大写
	public static String captureName(String name) {
		name = name.substring(0, 1).toUpperCase() + name.substring(1);
		return name;
	}
	//首字母转小写
	public static String toLowerCaseFirstOne(String s){
	  if(Character.isLowerCase(s.charAt(0)))
	    return s;
	  else
	    return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
	}

	/**
	 * base model 
	 */
	protected void wirtToFile(TableMeta tableMeta) throws IOException {
		
		String tableName = tableMeta.name;
		String fullTabelName = StrKit.firstCharToUpperCase(StrKit.toCamelCase(tableName));
		String pack = fullTabelName.replace(tableMeta.baseModelName.replace("Base", ""), "");
		pack = Common.underscoreName(pack);
		pack = File.separator+pack.toLowerCase().replace("_",File.separator);
		
		
		File dir = new File(baseModelOutputDir+pack);
		if (!dir.exists())
			dir.mkdirs();
		String target = baseModelOutputDir + pack + File.separator + tableMeta.baseModelName + ".java";
		FileWriter fw = new FileWriter(target);
		try {
			fw.write(tableMeta.baseModelContent);
		}
		finally {
			fw.close();
		}
	}
	
}
